package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"os"
)

type creq struct {
	clientID  string
	operation string
	timestamp int64
}

type Council struct {
	Id    string
	Addr  string
	Group int
}

type Node struct {
	Id    int
	Num   bool
	Table map[string]string
}

//节点池，主要用来存储监听地址
var NodeTable map[string]string

const prefixCMDLength = 20

/*
本部分测算一下耗时：
1， tcp 耗时 网络的第四层传输层
2，http 耗时 网络的第7层，应用层
3， rpc 调用耗时
*/
type Raft int

// PBFT 的节点池不应该是直接初始化的，而应该通过Raft 选举确定
func init() {
	NodeTable = make(map[string]string)
}

//rpc服务注册,并开启节点监听
func rpcRegister(raft *Raft) {
	//注册一个服务器
	err := rpc.RegisterName("raft", new(Raft))
	if err != nil {
		log.Panic(err)
	}
	addr := "127.0.0.1:8234"
	listen, err := net.Listen("tcp", addr)
	if err != nil {
		log.Panic(err)
	}
	fmt.Printf("节点开启监听:%s\n", addr)
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		rpc.ServeConn(conn)
		if err != nil {
			log.Panic(err)
		}
		b, err := ioutil.ReadAll(conn)
		if err != nil {
			log.Panic(err)
		}
		fmt.Println(b)
		//rf.handleRequest(b)
	}
}

func httpserver() {
	http.HandleFunc("/tpost", tpost)

	err := http.ListenAndServe(":8234", nil)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
}

func tpost(w http.ResponseWriter, r *http.Request) {
	msg := r.PostFormValue("message")
	fmt.Println(msg)
	// reply := []byte("success")
	// w.Write(reply)
	// msg := &creq{}
	// req, _ := ioutil.ReadAll(r.Body)
	// json.Unmarshal(req, &msg)
	// // err := json.NewDecoder(r.Body).Decode(&msg)
	// // if err != nil {
	// // 	fmt.Println("err msg")
	// // 	fmt.Println(err)
	// // 	return
	// // }

	// fmt.Println(msg)
}

// 下发文件
func tcpserver() {
	listen, err := net.Listen("tcp", "127.0.0.1:8235")
	fmt.Println("监听：8235")
	if err != nil {
		log.Panic(err)
	}
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		fmt.Println(conn.RemoteAddr(), "连接成功")
		if err != nil {
			log.Panic(err)
		}
		// buf := make([]byte, 4096)
		// n, err := conn.Read(buf)
		// if err != nil {
		// 	log.Panic(err)
		// }
		// fmt.Println(string(buf[:n]))
		// if string(buf[:n]) != "Download" {
		// 	fmt.Println("!Download")
		// 	return
		// }
		// 下发文件
		//path := "council.json"
		//testFileSend(path, conn)
	}
}

func rpchttpserver() {
	err := rpc.Register(new(Raft))
	if err != nil {
		log.Panic(err)
	}
	rpc.HandleHTTP()

	err = http.ListenAndServe("127.0.0.1:8236", nil)
	if err != nil {
		fmt.Println("注册rpc服务失败", err)
	}
}

func (rf *Raft) Link(req string, reply *Node) error {

	fmt.Println(req, "地址", &reply)
	reply.Id = 1
	reply.Num = true
	reply.Table = make(map[string]string)
	reply.Table["0"] = "aapple"
	reply.Table["1"] = "banana"
	reply.Table["2"] = "curve"

	fmt.Println(reply.Id, reply.Table, reply.Num)
	return nil
}
func rpctcpserver() {
	err := rpc.Register(new(Raft))
	if err != nil {
		log.Panic(err)
	}
	listen, err := net.Listen("tcp", "127.0.0.1:8237")
	if err != nil {
		log.Panic(err)
	}
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		if err != nil {
			log.Panic(err)
		}
		// b, err := ioutil.ReadAll(conn)
		// if err != nil {
		// 	log.Panic(err)
		// }
		// fmt.Println(string(b))
		go rpc.ServeConn(conn)

		//handleRequest(b)
	}
}

func testFileSend(path string, conn net.Conn) {
	defer conn.Close()
	// 发送文件名
	_, err := conn.Write([]byte(path))
	if err != nil {
		fmt.Println("conn.Write err", err)
		return
	}

	buf := make([]byte, 4096)
	n, err := conn.Read(buf)
	if err != nil {
		fmt.Println("conn.Read err", err)
		return
	}
	//返回ok，可以传输文件
	if string(buf[:n]) != "ok" {
		fmt.Println("!ok")
		return
	}

	fs, err := os.Open(path)
	defer fs.Close()

	if err != nil {
		fmt.Println("open err")
		return
	}

	buf = make([]byte, 1024*10)

	for {
		n, err := fs.Read(buf)
		if err == io.EOF {
			fmt.Println("文件读取完毕")
			return
		}
		if err != nil {
			fmt.Println("file.Read err:", err)
			return
		}
		_, err = conn.Write(buf[:n])
		if err != nil {
			fmt.Println("conn.Write err:", err)
			return
		}
	}
}

func main2() {
	tcpserver()
}

func main() {
	if os.Args[1] == "1" {
		httpserver()
	}
	if os.Args[1] == "2" {
		tcpserver()
	}
	if os.Args[1] == "3" {
		rpchttpserver()
	}
	if os.Args[1] == "4" {
		rpctcpserver()
	}
}

func tcp() {
	listen, err := net.Listen("tcp", "127.0.0.1:8235")
	fmt.Println("监听：8235")
	if err != nil {
		log.Panic(err)
	}
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		fmt.Println(conn.RemoteAddr(), "连接成功")
		if err != nil {
			log.Panic(err)
		}
	}
}
